package rsschart.charter;

import java.util.Iterator;

import rsschart.feed.Category;
import rsschart.feed.DataSet;
import rsschart.feed.DataSets;
import rsschart.feed.RssChart;

public class LineChart extends LineBarCharter implements Charter {

	final int TITLE_Y = 15;
	final int CATG_LABEL_Y = 210;
	final int CATG_TITLE_Y = 220;
	final int Y_AXIS_LABEL_X = 10;
	final int Y_AXIS_LABEL_Y = 110;
	final int Y_AXIS_SIZE = 180;
	final int CHART_TOP = 20;
	final int CHART_X_START = 50;
	
	public String draw(RssChart chart) {
		String[] LINE_COLOR;
		LINE_COLOR = new String[20];
		//to do: array of line colors
		
		StringBuffer chartSvg = new StringBuffer();
				
		int chartWidth;
		int textCenter;
		boolean legend=false;

		double currentX;

//		int numDataSets = chart.getDataSets().size(); 
		int pointCount;
		double minVal;
		double maxVal;
		double maxValTick;
		double minValTick;
		
		int maxLog;
		int minLog;
		//-- horizontal space for each bar set
		double catgWidth;
		double valsPerPoint;
		double zeroY;
		
		//-- set the bar area of the chart
		if(legend) {
			chartWidth = 200;
			textCenter = 140;
		}
		else {
			chartWidth = 250;
			textCenter = 175;
		}
		//-- chart object has to be initialized and valid for this call to work
		
		pointCount = chart.getSeriesPointCount();
		catgWidth = chartWidth / (pointCount-1);

		//-- draw header svg
		chartSvg.append(CharterUtil.getHeader(chart.getWidth(), chart.getHeight()));
		chartSvg.append("<!-- end header info -->\n");
		
		//-- add javascript method for clicking:
		chartSvg.append("\n<!-- onclick method -->\n");
		chartSvg.append(CharterUtil.getClickMethod());

		//-- draw click instruction:
		chartSvg.append("\n<!-- click instruction -->\n");
		chartSvg.append(CharterUtil.clickNote());
		
		//-- draw the title
		chartSvg.append("\n<!-- title -->\n");
		chartSvg.append(CharterUtil.getTitle(textCenter, TITLE_Y, chart.getTitle()));

		//-- draw chart frame
		chartSvg.append(CharterUtil.getChartFrame(CHART_X_START, CHART_TOP, chartWidth, Y_AXIS_SIZE));
		
		//-- find the y-axis bounds
		minVal = getMinValue(chart.getDataSets());
		minVal = minVal > 0 ? 0 : minVal;
		maxVal = getMaxValue(chart.getDataSets());
		
		//--
		maxLog = (int)Math.log10(maxVal);
		minLog=0;
		if (minVal!=0) {		
			minLog = (int)Math.log10(Math.abs(minVal));
		}
		
		//-- this section sets the maximum and minimum y bounds of the chart based on the size of the max/min val numbers
		double maxFull, maxHalf;
		double minFull, minHalf;
		
		maxFull = (int)(maxVal / Math.pow(10, maxLog)) * Math.pow(10, maxLog) 
			+ Math.pow(10, maxLog);
		maxHalf = (int)(maxVal / Math.pow(10, maxLog)) * Math.pow(10, maxLog) 
			+ Math.pow(10, maxLog)/2;
		if (maxVal>maxHalf) {
			maxValTick = maxFull;
		}
		else {
			maxValTick = maxHalf;
		}
		
		minValTick = 0;
		if (minVal!=0) {
			minFull = -1.0 * (int)(Math.abs(minVal) / Math.pow(10, minLog)) 
				* Math.pow(10, minLog) + Math.pow(10, minLog);
			minHalf = -1.0 * (int)(Math.abs(minVal) / Math.pow(10, minLog)) 
				* Math.pow(10, minLog) + Math.pow(10, minLog)/2;
			if (Math.abs(minVal)>Math.abs(minHalf)) {
				minValTick = minFull;
			}
			else {
				minValTick = minHalf;
			}
		}

		valsPerPoint = (maxValTick - minValTick)/ Y_AXIS_SIZE;
		
		//-- where is the Y=zero point? (:
		zeroY = maxValTick/(maxValTick-minValTick) * Y_AXIS_SIZE + CHART_TOP;
		
		//-- draw bars and labels for each category:
		//-- the standard bar chart works on one data series:
		String link = "./clickChart";
		DataSets dataSets;
		DataSet dataSet;
		Iterator setIter;
		Category category;
		dataSets = chart.getDataSets();
		category = chart.getCategory();
		String[] values;

		String dataSetsName = chart.getDataSetsName();
		String dataSetValueLabel = chart.getDataSetsValueLabel();
		String dataSetName;
		String catgName = category.getName();
		String[] catgLabels = category.getValue(); 
		double value=0.0;	

		StringBuffer lines = new StringBuffer();
		StringBuffer catgLabelContent = new StringBuffer();
		
		double previousX;
		double previousVal=0;
		
		chartSvg.append("<!-- draw lines-->\n");
		
		setIter = dataSets.iterator();
		while (setIter.hasNext()) {
			dataSet = (DataSet)setIter.next();
			values = dataSet.getValue();
			dataSetName = dataSet.getName();

			currentX = CHART_X_START;
			previousX = CHART_X_START;
			
			for (int i=0; i<pointCount;i++) {
				if (values.length>=i) {
					value = Double.parseDouble(values[i]);
					lines.append(drawLine(currentX, previousX, value, previousVal, valsPerPoint, zeroY, 
							                  link, catgName, catgLabels[i], dataSetsName, dataSetName));
					//-- next starting point; don't increment previousX until the second point is done:
					if (previousX!=currentX) {
						previousX += catgWidth;
					}
					currentX += catgWidth;
					previousVal = value;
				}
			}
		}
			
		//-- draw category labels once:
		currentX = CHART_X_START;
		for (int i=0; i<pointCount;i++) {			
			catgLabelContent.append(drawCatgLabel(currentX, CATG_LABEL_Y, catgLabels[i]));
			currentX += catgWidth;
		}
		
		chartSvg.append(lines.toString());
		chartSvg.append("<!-- category lables -->\n");
		chartSvg.append(catgLabelContent.toString());
		
		//-- draw y-axis ticks:
		double tickIncVal;
		double currentTickVal;
		double yTick;
		double tickBase;
		tickIncVal = getTickIncVal(maxValTick, minValTick);
		currentTickVal=tickIncVal;
		//-- draw above zero ticks:
		chartSvg.append("<!-- tick marks -->\n");
		if (maxVal > 0) {
			tickBase = zeroY;
			while(currentTickVal<=maxValTick) {
				yTick = tickBase - (tickIncVal/valsPerPoint);
				chartSvg.append(drawTickMark(currentTickVal, yTick));
				tickBase =yTick;
				currentTickVal += tickIncVal;
			}
		}
		//-- draw below zero ticks:
		
		//-- draw category title
		chartSvg.append(drawCatgLabel(textCenter, CATG_TITLE_Y, catgName));
		
		//-- draw y-axis label:
		chartSvg.append(drawYAxisLabel(Y_AXIS_LABEL_X, Y_AXIS_LABEL_Y, "Label"));


		


		chartSvg.append(CharterUtil.getClose());
		return chartSvg.toString();

	}

	private String drawLine(double startX, 
							double previousX, 
							double value, 
							double previousValue,
							double scaleFactor, 
							double zeroY,
							String linkUrl,
							String catg,
							String catgVal,
							String dataSet,
							String dataSetVal) {
		
		StringBuffer line = new StringBuffer();
		line.append("");

		String onclick;
		//double x;
		double y;
		double prevY;
		
		//-- can simplify this...
		y = zeroY - (value/scaleFactor);
		prevY = zeroY - (previousValue/scaleFactor);
		//x = startX; 
				
		onclick = CharterUtil.getDoLink("doLink", linkUrl, catg, catgVal, dataSet, dataSetVal, Double.toString(value));

		 line.append("<circle cx=\""+ startX + "\" cy=\""+ y + "\" r=\"2\" fill=\"" + "#336699" + 
				 	"\" stroke=\"none\"  stroke-width=\"0\"" +
					" onclick='" + onclick + "'/>\n");
		 if (startX != previousX) {
			 line.append("<line x1=\""+ previousX + "\" y1=\""+ prevY + "\"" + 
					 " x2=\"" + startX + "\" y2=\""+ y +"\"" + 
				 	" stroke=\"#336699\"  stroke-width=\"1\"" +
					" onclick='" + onclick + "'/>\n");
		 }
		 
	
		return line.toString();
	}

}
